package zy.service.sell.voucher.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import zy.dao.money.bank.BankDAO;
import zy.dao.money.bank.BankRunDAO;
import zy.dao.sell.voucher.VoucherDAO;
import zy.entity.PageData;
import zy.entity.PageInfo;
import zy.entity.money.bank.T_Money_Bank;
import zy.entity.money.bank.T_Money_BankRun;
import zy.entity.sell.voucher.T_Sell_Voucher;
import zy.entity.sell.voucher.T_Sell_VoucherList;
import zy.service.sell.voucher.VoucherService;
import zy.util.CommonUtil;
import zy.util.DateUtil;
import zy.util.StringUtil;

@Service
public class VoucherServiceImpl implements VoucherService{
	@Resource
	private VoucherDAO voucherDAO;
	@Resource
	private BankDAO bankDAO;
	@Resource
	private BankRunDAO bankRunDAO;

	@Override
	public PageData<T_Sell_Voucher> page(Map<String, Object> params) {
		Object companyid = params.get(CommonUtil.COMPANYID);
		Object pageSize = params.get(CommonUtil.PAGESIZE);
		Object pageIndex = params.get(CommonUtil.PAGEINDEX);
		if (companyid == null) {
			throw new IllegalArgumentException("连接超时，请重新登录!");
		}
		Integer _pageSize = (Integer)pageSize;
		Integer _pageIndex = (Integer)pageIndex;
		
		Integer totalCount = voucherDAO.count(params);
		PageInfo pageInfo = new PageInfo(totalCount, _pageSize, _pageIndex);
		params.put(CommonUtil.START, (_pageIndex-1)*_pageSize);
		params.put(CommonUtil.END, _pageSize);
		
		List<T_Sell_Voucher> list = voucherDAO.list(params);
		PageData<T_Sell_Voucher> pageData = new PageData<T_Sell_Voucher>();
		pageData.setPageInfo(pageInfo);
		pageData.setList(list);
		return pageData;
	}
	
	@Override
	public PageData<T_Sell_VoucherList> pageDetail(Map<String, Object> params) {
		Object companyid = params.get(CommonUtil.COMPANYID);
		Object pageSize = params.get(CommonUtil.PAGESIZE);
		Object pageIndex = params.get(CommonUtil.PAGEINDEX);
		if (companyid == null) {
			throw new IllegalArgumentException("连接超时，请重新登录!");
		}
		Integer _pageSize = (Integer)pageSize;
		Integer _pageIndex = (Integer)pageIndex;
		
		Integer totalCount = voucherDAO.countDetail(params);
		PageInfo pageInfo = new PageInfo(totalCount, _pageSize, _pageIndex);
		params.put(CommonUtil.START, (_pageIndex-1)*_pageSize);
		params.put(CommonUtil.END, _pageSize);
		
		List<T_Sell_VoucherList> list = voucherDAO.listDetail(params);
		PageData<T_Sell_VoucherList> pageData = new PageData<T_Sell_VoucherList>();
		pageData.setPageInfo(pageInfo);
		pageData.setList(list);
		return pageData;
	}
	
	@Override
	public T_Sell_Voucher queryByID(Integer vc_id) {
		return voucherDAO.queryByID(vc_id);
	}
	
	@Override
	public List<T_Sell_VoucherList> listDetail(String vc_code, Integer companyid) {
		if (companyid == null) {
			throw new IllegalArgumentException("连接超时，请重新登录!");
		}
		if (vc_code == null) {
			throw new IllegalArgumentException("参数vc_code不能为null");
		}
		return voucherDAO.listDetail(vc_code, companyid);
	}
	
	@Override
	@Transactional
	public void save(Map<String, Object> params) {
		if(params == null){
			throw new IllegalArgumentException("参数不能为null");
		}
		T_Sell_Voucher voucher = (T_Sell_Voucher)params.get("voucher");
		if (voucher.getVc_realcash() > voucher.getVc_money()) {
			throw new IllegalArgumentException("实收现金必须小于每张面值");
		}
		String start_no = (String)params.get("start_no");
		String mark = (String)params.get("mark");
		String vcl_ba_code = (String)params.get("vcl_ba_code");
		Integer add_count = (Integer)params.get("add_count");
		Integer prefix = (Integer)params.get("prefix");
		List<T_Sell_Voucher> vouchers = new ArrayList<T_Sell_Voucher>();
		List<T_Sell_VoucherList> voucherDetails = new ArrayList<T_Sell_VoucherList>();
		String beginCode = StringUtils.stripStart(start_no, "0");//去掉前置0
		long beginIndex = 0;
		if (!"".equals(beginCode)) {
			beginIndex = Long.parseLong(beginCode);
		}
		long endIndex = beginIndex + add_count - 1;
		int length = Math.max(start_no.length(), StringUtil.trimString(endIndex).length());
		String format = "%0" + length + "d";
		String cardcode = null;
		List<String> vc_cardcode = new ArrayList<String>();
		for (int i = 0; i < add_count; i++) {
			if(prefix.equals(0)){
				cardcode = mark+String.format(format, beginIndex + i);
			}else {
				cardcode = String.format(format, beginIndex + i)+mark;
			}
			T_Sell_Voucher item = null;
			T_Sell_VoucherList itemDetail = null;
			try {
				item = (T_Sell_Voucher)voucher.clone();
				item.setVc_cardcode(cardcode);
				itemDetail = new T_Sell_VoucherList();
				itemDetail.setCompanyid(item.getCompanyid());
				itemDetail.setVcl_cardcode(cardcode);
				itemDetail.setVcl_ba_code(vcl_ba_code);
				itemDetail.setVcl_cash(item.getVc_realcash());
				itemDetail.setVcl_money(item.getVc_money());
				itemDetail.setVcl_manager(item.getVc_manager());
				itemDetail.setVcl_shop_code(item.getVc_shop_code());
				itemDetail.setVcl_type(0);
				itemDetail.setVcl_date(DateUtil.getCurrentTime());
			} catch (CloneNotSupportedException e) {
				throw new IllegalArgumentException("对象深拷贝异常");
			}
			vouchers.add(item);
			voucherDetails.add(itemDetail);
			vc_cardcode.add(cardcode);
		}
		//1.检测代金券号是否已经存在
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("vc_cardcode", vc_cardcode);
		paramMap.put("companyid", voucher.getCompanyid());
		int existCount = voucherDAO.countByCardCode(paramMap);
		if (existCount > 0) {
			throw new IllegalArgumentException("代金券号已经存在");
		}
		//2.保存代金券主表和明细表
		voucherDAO.save(vouchers, voucherDetails);
		//3.更新银行帐目和银行流水
		T_Money_Bank bank = bankDAO.queryByCode(vcl_ba_code, voucher.getCompanyid());
		Double beginBalance = bank.getBa_balance() == null ? 0d : bank.getBa_balance();
		bank.setBa_balance(beginBalance + voucher.getVc_realcash() * add_count);
		bankDAO.updateBalanceById(bank);
		List<T_Money_BankRun> bankRuns = new ArrayList<T_Money_BankRun>();
		T_Money_BankRun run = null;
		for (int i=0;i<vouchers.size();i++) {
			T_Sell_Voucher item =vouchers.get(i);
			run = new T_Money_BankRun();
			run.setBr_ba_code(vcl_ba_code);
			run.setBr_balance(beginBalance + (i + 1) * item.getVc_realcash());
			run.setBr_bt_code(CommonUtil.BANKRUN_VOUCHER);
			run.setBr_date(item.getVc_grantdate());
			run.setBr_enter(item.getVc_realcash());
			run.setBr_manager(item.getVc_manager());
			run.setBr_number(item.getVc_code());
			run.setBr_remark(item.getVc_remark());
			run.setBr_shop_code(bank.getBa_shop_code());
			run.setBr_sysdate(DateUtil.getCurrentTime());
			run.setCompanyid(item.getCompanyid());
			bankRuns.add(run);
		}
		bankRunDAO.save(bankRuns);
	}
	
	@Override
	public void update(T_Sell_Voucher voucher) {
		if (voucher == null || voucher.getVc_id() == null) {
			throw new IllegalArgumentException("参数vc_id不能为null");
		}
		voucherDAO.update(voucher);
	}

	@Override
	public void updateState(T_Sell_Voucher voucher) {
		if (voucher == null || voucher.getVc_id() == null) {
			throw new IllegalArgumentException("参数vc_id不能为null");
		}
		voucherDAO.updateState(voucher);
	}

	@Override
	public void del(Integer vc_id) {
		if (vc_id == null) {
			throw new IllegalArgumentException("参数vc_id不能为null");
		}
		T_Sell_Voucher voucher = voucherDAO.queryByID(vc_id);
		if (voucher == null) {
			throw new RuntimeException("代金券不存在或已删除！");
		}
		if (voucher.getVc_used_money() > 0) {
			throw new RuntimeException("代金券已使用，不能被删除！");
		}
		//1.更新银行帐目，产生账目回流银行流水
		String ba_code = voucherDAO.queryInitBank(voucher.getVc_code(), voucher.getCompanyid());
		if(ba_code != null){
			T_Money_Bank bank = bankDAO.queryByCode(ba_code, voucher.getCompanyid());
			Double beginBalance = bank.getBa_balance() == null ? 0d : bank.getBa_balance();
			bank.setBa_balance(beginBalance - voucher.getVc_realcash());
			bankDAO.updateBalanceById(bank);
			T_Money_BankRun run = new T_Money_BankRun();
			run.setBr_ba_code(ba_code);
			run.setBr_balance(bank.getBa_balance());
			run.setBr_bt_code(CommonUtil.BANKRUN_VOUCHER);
			run.setBr_date(DateUtil.getCurrentTime());
			run.setBr_out(voucher.getVc_realcash());
			run.setBr_manager(voucher.getVc_manager());
			run.setBr_number(voucher.getVc_code());
			run.setBr_remark("删除代金券["+voucher.getVc_cardcode()+"]，银行帐目回流。");
			run.setBr_shop_code(bank.getBa_shop_code());
			run.setBr_sysdate(DateUtil.getCurrentTime());
			run.setCompanyid(voucher.getCompanyid());
			bankRunDAO.save(run);
		}
		//2.删除代金券主表和子表数据
		voucherDAO.del(vc_id);
		voucherDAO.delList(voucher.getVc_code(), voucher.getCompanyid());
	}
    //--------------------------------------前台功能-------------------------------------
	@Override
	public List<T_Sell_Voucher> listShop(Map<String, Object> params) {
		Object companyid = params.get(CommonUtil.COMPANYID);
		if (companyid == null) {
			throw new IllegalArgumentException("连接超时，请重新登录!");
		}
		List<T_Sell_Voucher> list = voucherDAO.listShop(params);
		return list;
	}
	@Transactional
	@Override
	public void saveShop(Map<String, Object> params) {
		if(params == null){
			throw new IllegalArgumentException("参数不能为null");
		}
		T_Sell_Voucher voucher = (T_Sell_Voucher)params.get("voucher");
		if (voucher.getVc_realcash() > voucher.getVc_money()) {
			throw new IllegalArgumentException("实收现金必须小于每张面值");
		}
		params.put("vc_cardcode", voucher.getVc_cardcode());
		Integer _id = voucherDAO.idByCardCode(params);
		if(null != _id && _id > 0){
			throw new IllegalArgumentException("券号已经存在");
		}
		voucherDAO.saveShop(params);
		T_Money_Bank bank = bankDAO.queryByCode(voucher.getVcl_ba_code(), voucher.getCompanyid());
		Double beginBalance = bank.getBa_balance() == null ? 0d : bank.getBa_balance();
		bank.setBa_balance(beginBalance + voucher.getVc_realcash());
		bankDAO.updateBalanceById(bank);
		T_Money_BankRun run = new T_Money_BankRun();
		run.setBr_ba_code(voucher.getVcl_ba_code());
		run.setBr_balance(beginBalance + voucher.getVc_realcash());
		run.setBr_bt_code(CommonUtil.BANKRUN_VOUCHER);
		run.setBr_date(voucher.getVc_grantdate());
		run.setBr_enter(voucher.getVc_realcash());
		run.setBr_manager(voucher.getVc_manager());
		run.setBr_number(voucher.getVc_cardcode());
		run.setBr_remark(voucher.getVc_remark());
		run.setBr_shop_code(bank.getBa_shop_code());
		run.setBr_sysdate(DateUtil.getCurrentTime());
		run.setCompanyid(voucher.getCompanyid());
		bankRunDAO.save(run);
	}

	@Override
	public T_Sell_Voucher queryByCode(Map<String, Object> param) {
		return voucherDAO.queryByCode(param);
	}
	
	
}
